import {CN,EN,Web,Cst,Action,Icon} from '../../config'
import {LineStyle} from '../../config/plugins-config'
import cssText from './index.jcss'
import Plugin from '../plugin'
import Utils from '../../utils'
import VFMixin from '../vf.mixin'
import * as VersionItem from './template'
import {
	Mat,ColorStyle,PointLabelMap
} from './config'

const DataSource = {LineStyle}
export default class VersionMng extends Plugin{
	constructor(...args){
		super(...args)
		this.name = "VersionMng"
		this.createClassName({
			root:"version-panel",
			itemWrap:"step-item-wrap",
			emptyItemWrap:"empty-item-wrap"
		})
		this.injectStyle(cssText,this.cn)
		this.mixin(VFMixin)
		this.render()
		this.bind()
	}
	render(){
		let cn = this.cn
		this.$dom = document.createDOM("div",{
			id:cn.root,
			class:cn.root
		})
		this.$dom.innerHTML=`
			<div class="${CN.leftTopInputWrap}">
			<p>
			<input spellcheck="false" class="${CN.input}"/>
			<span class="${Icon.search} ${CN.iconfont} ${CN.inputAddon} ${CN.l}"></span>
			</p>
			</div>
			<div class="${CN.leftItemsPanel}"></div>
		`
		this.searchIp = this.$dom.query("input")
		this.itemsPanel = this.$dom.query("."+CN.leftItemsPanel)

		this.$event.emit(EN.left_layout_render,this.$dom,this.name)
	}
	bind(){
		this.$dom.addEventListener("click",(e)=>{
			if(!this.active)return
			let action = e.target.dataset.action
			this[action]&&this[action](e)
		})
		this.searchIp.addEventListener("focusin",(e)=>{
			this.searchIp.select()
		})
		this.searchIp.addEventListener("input",(e)=>{
			this.onSearch.functional(this,e.target.nvalue)
		})
		this.itemsPanel.addEventListener("click",this.onItemClick.bind(this));
		["input","change"].forEach(en=>{
			this.itemsPanel
			.addEventListener(en,(e)=>{
				if(!this.active)return
				this.onInput.functional(this,e)
				let t = e.target
				if(t.type==="checkbox"&&e.type==="change")
					this.updateItemUi(t)
			})
		})
		this.on(Cst.focusIn,this.onFocusIn.bind(this))
	}
	onSearch(ip){
		this.itemsPanel.innerHTML=""
		let rs = this.cacheRs.filter(r=>{
			let reg = new RegExp(ip,"i")
			return reg.test(r.action)
		})
		if(rs.isEmpty())
			this.renderEmptyItem()
		else
		rs.forEach(r=>{
			this.renderStepItem(r)
		})
	}
	loadTpl(stepData){
		let layout = VersionItem.layout
		let action = stepData.rtype||stepData.action
		let tpl = VersionItem[stepData.action]
		let regStepNum = new RegExp(Mat.stepnum,"g")
		let regColor = new RegExp(Mat.color,"g")
		if(!tpl)return

		if(tpl.match(Mat.point)){
			let pointTpl = stepData.step.map((step,i)=>{
				let lts = PointLabelMap[action]||PointLabelMap.default
				let lt = lts[i]||lts[lts.length-1]
				return VersionItem.layout_point.
				replace(regStepNum,i).
				replace(Mat.labeltext,lt)
			}).join("\n")
			tpl = tpl.replace(Mat.point,pointTpl)
		}
		if(tpl.match(Mat.label))
			tpl = tpl.replace(Mat.label,VersionItem.layout_label)

		if(tpl.match(Mat.stroke)){
			let strokeTpl = VersionItem.layout_color
			.replace(regColor,ColorStyle.stroke.name)
			.replace(Mat.labeltext,ColorStyle.stroke.desc)
			tpl = tpl.replace(Mat.stroke,strokeTpl)
		}
		if(tpl.match(Mat.fill)){
			let fillTpl = VersionItem.layout_color
			.replace(regColor,ColorStyle.fill.name)
			.replace(Mat.labeltext,ColorStyle.fill.desc)
			tpl = tpl.replace(Mat.fill,fillTpl)
		}
		if(tpl.match(Mat.lineStyle))
			tpl = tpl.replace(Mat.lineStyle,VersionItem.layout_lineStyle)
		
		tpl = layout.replace(Mat.placeholder,tpl)
		return tpl
	}
	renderStepItem(stepData){
		let cn = this.cn
		let tpl = this.loadTpl(stepData)
		let action = stepData.rtype||stepData.action
		if(!tpl)return
		let data = 	cn.assign(cn,stepData)
		.assign({
			icon:Icon[action],
			iconeyeon:Icon.eyeon,
			iconeyeoff:Icon.eyeoff
		})
		.assign({ds:DataSource})

		let vdom = document.createDOM("div")
			vdom.innerHTML = Utils.parseCssText(tpl,data)
		this.itemsPanel.appendChild(vdom.firstElementChild)
	}
	renderEmptyItem(){
		let vdom = document.createDOM("div",{
			class:this.cn.emptyItemWrap
		})
			vdom.innerHTML = "<p>空空如也...</p>"
		this.itemsPanel.appendChild(vdom)
	}
	onInput(e){
		let t = e.target
		let ds = this.isItemWrapFocus(t).dataset;
		let save = e.type==="change"
		let raw = t.nvalue
		let command = t.dataset.command
		let data={
			command,
			value: raw
		}
		let r = this.getById(ds.id)
		if(r.action!==Action.FunctionTool){
			this.emit(EN.input_done,data,r,save)
			return
		}
		
		try{
			let path = command.split(".")
			if(path[0]==="step"){
				let fnMeta = raw
				if(!this.isValidFn(raw))return
				r.step[0].merge(fnMeta)
			}else if(path[0]==="state"){
				r.state[path[1]] = raw
			}
			this.emit(EN.input_done,r,save)
		}catch(e){
			console.error(e)
		}
	}
	updateItemUi(t){
		let itemWrap = this.isItemWrapFocus(t)
		let inputs = itemWrap.querySelectorAll("input:not([type=checkbox])")
		let checked = t.checked
		let pNode = t.parentNode
		pNode.classList.toggle(Icon.eyeon)
		pNode.classList.toggle(Icon.eyeoff)

		for(let i=0;i<inputs.length;i++)
			inputs[i].disabled = !checked;
	}
	onFocusIn(rs){
		this.itemsPanel.innerHTML=""
		this.cacheRs = rs
		if(rs.isEmpty())
			this.renderEmptyItem()
		else
		rs.forEach(r=>{
			this.renderStepItem(r)
		})
	}
	updateCache(r){
		let index = this.cacheRs.findIndex((s)=>s.id===r.id)
		this.cacheRs[index] = r
	}
}